/*******************************************************************************
 * Copyright (c) 2013 by mHealth Corporation all right reserved.
 * KFuPayDistAlgorithms.java
 * 2013-10-14 
 * 
 *******************************************************************************/
package com.zlq.cn.util.des.security;

import com.zlq.cn.util.des.hash.HrHex;

/**
 * <p>
 * business:
 * </p>
 * <p>
 * comment:
 * </p>
 * 
 * @version 2013-10-14
 * @author jimi yuan
 *         <p>
 *         History:
 *         </p>
 *         <p>
 *         1. Date:
 *         </p>
 *         <p>
 *         2. Author:
 *         </p>
 *         <p>
 *         3. Modification:
 *         </p>
 */
public class KFuPayDistAlgorithms {
	/**
	 * @param deviceKey
	 *            双倍长的系统设备管理密钥(hex字符串)
	 * @param deviceTSN
	 *            设备序列号(长度必须大于8,hex字符串)
	 * @return 返回设备主工作密钥(双倍长密钥外加四字节的校验数据组成，为40字节长度的hex字符串)
	 */
	public static String getWorkMasterKey(String deviceKey, String deviceTSN) {
		if (null == deviceKey || 32 != deviceKey.length() || null == deviceTSN
				|| 8 > deviceTSN.length()) {
			return null;
		}

		try {
			// 计算工作密钥左8字节
			byte[] byteKey = HrHex.decode(deviceKey);
			byte[] byteTsn = HrHex.decode(deviceTSN);

			byte[] srcLeft = new byte[8];
			for (int i = 0; i < srcLeft.length; i++) {
				srcLeft[i] = byteTsn[i];
			}

			byte[] tmkLeft = KFuPayTriDES.encryptWithPKCS5Padding(srcLeft, byteKey);

			// 计算工作密钥右8字节
			byte[] tsnRight = new byte[8];
			int start = byteTsn.length - 8;
			for (int i = start; i < byteTsn.length; i++) {
				tsnRight[i - start] = byteTsn[i];
			}
			byte[] srcRight = new byte[8];
			for (int i = 0; i < srcRight.length; i++) {
				srcRight[i] = (byte) (tmkLeft[i] ^ tsnRight[i]);
			}
			byte[] tmkRight = KFuPayTriDES.encryptWithPKCS5Padding(srcRight, byteKey);

			byte[] tmk = new byte[16];
			for (int i = 0; i < 8; i++) {
				tmk[i] = tmkLeft[i];
			}

			for (int i = 8; i < tmk.length; i++) {
				tmk[i] = tmkRight[i - 8];
			}

			byte[] srcCheck = new byte[8];
			for (int i = 0; i < srcCheck.length; i++) {
				srcCheck[i] = 0x00;
			}
			byte[] encryptCheck = KFuPayTriDES.encryptWithPKCS5Padding(srcCheck, tmk);

			byte[] result = new byte[20];
			for (int i = 0; i < tmk.length; i++) {
				result[i] = tmk[i];
			}
			for (int i = 16; i < result.length; i++) {
				result[i] = encryptCheck[i - 16];
			}

			return HrHex.encode(result);
		} catch (Exception e) {
		}

		return null;
	}

	/**
	 * @param workKey
	 *            双倍长的工作主密钥(hex字符串)
	 * @param random
	 *            分散数据(8字节的随机数，hex字符串)
	 * @return 返回传输过程密钥(双倍长hex字符串)
	 */
	public static String getTransKey(String workKey, String random) {
		if (null == workKey || 32 != workKey.length() || null == random || 16 != random.length()) {
			return null;
		}

		try {
			// 计算过程密钥左8字节
			byte[] byteKey = HrHex.decode(workKey);
			byte[] byteRandomRight = new byte[8];
			byte[] byteRandomLeft = HrHex.decode(random);
			for (int i = 0; i < byteRandomRight.length; i++) {
				byteRandomRight[i] = (byte) ~byteRandomLeft[i];
			}

			byte[] wkLeft = KFuPayTriDES.encryptWithPKCS5Padding(byteRandomLeft, byteKey);
			byte[] wkRight = KFuPayTriDES.encryptWithPKCS5Padding(byteRandomRight, byteKey);
			byte[] result = new byte[16];
			for (int i = 0; i < wkLeft.length; i++) {
				result[i] = wkLeft[i];
			}

			for (int i = 8; i < result.length; i++) {
				result[i] = wkRight[i - 8];
			}

			return HrHex.encode(result);
		} catch (Exception e) {
		}

		return null;
	}
}
